package cn.juque.jdfsystem.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.jwt.JWTUtil;
import cn.hutool.jwt.signers.AlgorithmUtil;
import cn.hutool.jwt.signers.JWTSigner;
import cn.hutool.jwt.signers.JWTSignerUtil;
import cn.juque.common.base.BaseOperator;
import cn.juque.common.base.BaseRequestVO;
import cn.juque.common.base.BaseResponseVO;
import cn.juque.common.base.PageInfo;
import cn.juque.common.constants.MessageEnum;
import cn.juque.common.constants.NumberConstant;
import cn.juque.jdfsystem.contants.BusinessConstants;
import cn.juque.jdfsystem.entity.UserInfo;
import cn.juque.jdfsystem.service.IUserInfoService;
import cn.juque.jdfsystem.vo.userinfo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author juque
 * @version 1.0.0
 * <ul>
 *     <li>UserInfoController</li>
 * </ul>
 * @date 2023-03-15 17:29:53
 **/
@Slf4j
@Controller
@RequestMapping("/jdf/user")
public class UserInfoController extends BaseController {

    @Resource
    private IUserInfoService userInfoService;

    /**
     * 查询
     *
     * @param request BaseRequestVO
     * @return BaseResponseVO
     */
    @PostMapping(value = "/login")
    @ResponseBody
    public BaseResponseVO<String> login(@RequestBody BaseRequestVO<LoginPramVO> request) {
        LoginPramVO param = super.validatorUtil.checkNotNull(request);
        UserInfo userInfo = this.userInfoService.login(param.getUsername(), param.getPassword());
        String token = this.createToken(userInfo);
        return new BaseResponseVO<>(MessageEnum.OK, token);
    }

    /**
     * 查询
     *
     * @param request BaseRequestVO
     * @return BaseResponseVO
     */
    @PostMapping(value = "/list")
    @ResponseBody
    public BaseResponseVO<List<UserInfoListVO>> list(@RequestBody BaseRequestVO<UserInfoSearchVO> request) {
        UserInfoSearchVO searchVO = super.validatorUtil.checkNotNull(request);
        PageInfo pageInfo = request.getPageInfo();
        super.validatorUtil.checkPageInfo(pageInfo);
        UserInfo userInfo = new UserInfo();
        BeanUtil.copyProperties(searchVO, userInfo);
        List<UserInfo> list = this.userInfoService.listInfoWithPage(pageInfo, userInfo);
        List<UserInfoListVO> voList = BeanUtil.copyToList(list, UserInfoListVO.class);
        return new BaseResponseVO<>(MessageEnum.OK, voList, pageInfo);
    }

    /**
     * 详情
     *
     * @return BaseResponseVO
     */
    @GetMapping(value = "/detailByCurrent")
    @ResponseBody
    public BaseResponseVO<UserInfoDetailVO> detailByCurrent() {
        BaseOperator baseOperator = super.parseOperator();
        UserInfo detail = this.userInfoService.detail(baseOperator.getOperatorId());
        UserInfoDetailVO detailVO = new UserInfoDetailVO();
        BeanUtil.copyProperties(detail, detailVO);
        return new BaseResponseVO<>(MessageEnum.OK, detailVO);
    }

    /**
     * 详情
     *
     * @param id 主键
     * @return BaseResponseVO
     */
    @GetMapping(value = "/detail")
    @ResponseBody
    public BaseResponseVO<UserInfoDetailVO> detail(String id) {
        Assert.notEmpty(id);
        UserInfo detail = this.userInfoService.detail(id);
        UserInfoDetailVO detailVO = new UserInfoDetailVO();
        BeanUtil.copyProperties(detail, detailVO);
        return new BaseResponseVO<>(MessageEnum.OK, detailVO);
    }

    /**
     * 新增
     *
     * @param request BaseRequestVO
     * @return BaseResponseVO
     */
    @PostMapping(value = "/add")
    @ResponseBody
    public BaseResponseVO<Boolean> add(@RequestBody BaseRequestVO<UserInfoAddVO> request) {
        super.validatorUtil.fastValidate(request);
        UserInfoAddVO addVO = request.getParam();
        UserInfo userInfo = new UserInfo();
        BeanUtil.copyProperties(addVO, userInfo);
        this.userInfoService.saveInfo(userInfo);
        return new BaseResponseVO<>(MessageEnum.OK, true);
    }

    /**
     * 更新
     *
     * @param request BaseRequestVO
     * @return BaseResponseVO
     */
    @PostMapping(value = "/edit")
    @ResponseBody
    public BaseResponseVO<Boolean> edit(@RequestBody BaseRequestVO<UserInfoUpdateVO> request) {
        super.validatorUtil.fastValidate(request);
        UserInfoUpdateVO updateVO = request.getParam();
        UserInfo userInfo = new UserInfo();
        BeanUtil.copyProperties(updateVO, userInfo);
        this.userInfoService.updateInfo(userInfo);
        return new BaseResponseVO<>(MessageEnum.OK, true);
    }

    /**
     * 删除
     *
     * @param request BaseRequestVO
     * @return BaseResponseVO
     */
    @PostMapping(value = "/delete")
    @ResponseBody
    public BaseResponseVO<Boolean> delete(@RequestBody BaseRequestVO<UserInfoDeleteVO> request) {
        super.validatorUtil.fastValidate(request);
        List<String> idList = request.getParam().getIdList();
        this.userInfoService.deleteInfo(idList);
        return new BaseResponseVO<>(MessageEnum.OK, true);
    }

    /**
     * 创建token
     *
     * @param userInfo UserInfo
     * @return String
     */
    private String createToken(UserInfo userInfo) {
        Date date = DateUtil.offsetHour(new Date(), NumberConstant.THIRTY_TWO);
        Map<String, Object> payload = MapUtil.newHashMap();
        payload.put(BusinessConstants.USER_ID, userInfo.getId());
        payload.put(BusinessConstants.USER_NAME, userInfo.getUserName());
        payload.put(BusinessConstants.EXPIRE_TIME, date.getTime());
        JWTSigner jwtSigner = JWTSignerUtil.createSigner(AlgorithmUtil.getId("HS256"), userInfo.getId().getBytes(StandardCharsets.UTF_8));
        return BusinessConstants.TOKEN_PREFIX + JWTUtil.createToken(payload, jwtSigner);
    }
}
